

Extern "Windows-MS"
	Declare Function MakeLng(lo32 As Integer, Hi32 As Integer) As LongInt
	Declare Function Folder_LenEx(sPath As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As ULongInt
	Declare Function Folder_Copy(sPathSrc As ZString Ptr, sPathDst As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As UInteger
	Declare Function Folder_Move(sPathSrc As ZString Ptr, sPathDst As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As UInteger
	Declare Function Folder_Delete(sPath As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As UInteger
End Extern

Type Folder_Execute_Info
	DstPath As ZString Ptr
	Filter As ZString Ptr
	FileCount As UInteger
	FileSize As ULongInt
	IsRecu As Integer
End Type



Function ScanFile_Proc(Path As ZString Ptr, FindData As WIN32_FIND_DATA Ptr, param As Integer = 0) As Integer
	If param And 4 Then
		If FindData->dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
			Return 0
		EndIf
	EndIf
	AutoFreeBuffer.PutData(*Path & FindData->cFileName & !"\r\n")
End Function

Function ScanName_Proc(Path As ZString Ptr, FindData As WIN32_FIND_DATA Ptr, param As Integer = 0) As Integer
	If param And 4 Then
		If FindData->dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
			Return 0
		EndIf
	EndIf
	AutoFreeBuffer.PutData(FindData->cFileName & !"\r\n")
End Function

Function SizePath_Proc(Path As ZString Ptr, FindData As WIN32_FIND_DATA Ptr, param As Integer = 0) As Integer
	Dim pInfo As Folder_Execute_Info Ptr = Cast(Any Ptr, param)
	If FindData->dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
		pInfo->FileSize += Folder_LenEx(*Path & FindData->cFileName & "\", pInfo->Filter, pInfo->IsRecu)
	Else
		pInfo->FileSize += MakeLng(FindData->nFileSizeLow, FindData->nFileSizeHigh)
	EndIf
	Return 0
End Function

Function CopyPath_Proc(Path As ZString Ptr, FindData As WIN32_FIND_DATA Ptr, param As Integer = 0) As Integer
	Dim pInfo As Folder_Execute_Info Ptr = Cast(Any Ptr, param)
	If FindData->dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
		pInfo->FileCount += Folder_Copy(*Path & FindData->cFileName & "\", *pInfo->DstPath & FindData->cFileName & "\", pInfo->Filter, pInfo->IsRecu)
	Else
		If CopyFile(*Path & FindData->cFileName, *pInfo->DstPath & FindData->cFileName, FALSE) Then
			pInfo->FileCount += 1
		EndIf
	EndIf
	Return 0
End Function

Function MovePath_Proc(Path As ZString Ptr, FindData As WIN32_FIND_DATA Ptr, param As Integer = 0) As Integer
	Dim pInfo As Folder_Execute_Info Ptr = Cast(Any Ptr, param)
	If FindData->dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
		pInfo->FileCount += Folder_Move(*Path & FindData->cFileName & "\", *pInfo->DstPath & FindData->cFileName & "\", pInfo->Filter, pInfo->IsRecu)
	Else
		If MoveFileEx(*Path & FindData->cFileName, *pInfo->DstPath & FindData->cFileName, MOVEFILE_REPLACE_EXISTING Or MOVEFILE_COPY_ALLOWED Or MOVEFILE_WRITE_THROUGH) Then
			pInfo->FileCount += 1
		EndIf
	EndIf
	Return 0
End Function

Function DeletePath_Proc(Path As ZString Ptr, FindData As WIN32_FIND_DATA Ptr, param As Integer = 0) As Integer
	Dim pInfo As Folder_Execute_Info Ptr = Cast(Any Ptr, param)
	If FindData->dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY Then
		pInfo->FileCount += Folder_Delete(*Path & FindData->cFileName & "\", pInfo->Filter, pInfo->IsRecu)
	Else
		If DeleteFile(*Path & FindData->cFileName) Then
			pInfo->FileCount += 1
		EndIf
	EndIf
	Return 0
End Function



Extern "Windows-MS"
	
	Function File_List(sPath As ZString Ptr, sFilt As ZString Ptr, iAttr As Integer, iAtex As Integer, iRecu As Integer) As ZString Ptr Export
		AutoFreeBuffer.FreeMemory()
		xRtl.File.Scan(sPath, sFilt, iAttr, iAtex, iRecu, @ScanFile_Proc, iAtex)
		If AutoFreeBuffer.BufferMemory Then
			AutoFreeBuffer.BufferMemory[AutoFreeBuffer.BufferUseLen - 2] = 0
			Return AutoFreeBuffer.BufferMemory
		Else
			Return @xRtl.xywh_library_xrtl_memory_snull
		EndIf
	End Function
	
	Function File_ListName(sPath As ZString Ptr, sFilt As ZString Ptr, iAttr As Integer, iAtex As Integer) As ZString Ptr Export
		AutoFreeBuffer.FreeMemory()
		xRtl.File.Scan(sPath, sFilt, iAttr, iAtex, 0, @ScanName_Proc, iAtex)
		If AutoFreeBuffer.BufferMemory Then
			AutoFreeBuffer.BufferMemory[AutoFreeBuffer.BufferUseLen - 2] = 0
			Return AutoFreeBuffer.BufferMemory
		Else
			Return @xRtl.xywh_library_xrtl_memory_snull
		EndIf
	End Function
	
	Function File_Read(sPath As ZString Ptr) As ZString Ptr Export
		Dim TempPtr As ZString Ptr
		If xRtl.File.eRead(sPath, @TempPtr) Then
			Return TempPtr
		Else
			Return @xRtl.xywh_library_xrtl_memory_snull
		EndIf
	End Function
	
	Function File_ReadEx(sPath As ZString Ptr, iAddr As UInteger, iSize As UInteger, eChar As UInteger) As ZString Ptr Export
		If iSize = 0 Then
			iSize = xRtl.File.Size(sPath) - iAddr
		EndIf
		If iSize > 0 Then
			Dim TempPtr As ZString Ptr = xRtl.TempMemory(iSize + 4)
			If xRtl.File.Read(sPath, TempPtr, iAddr, iSize) Then
				For i As Integer = iSize To iSize + 3
					TempPtr[i] = 0
				Next
				Select Case eChar
					Case 1
						' unicode
						Return xRtl.Charset.W2A(Cast(Any Ptr, TempPtr))
					Case 2
						' utf-8
						Return xRtl.Charset.U2A(TempPtr)
					Case Else
						' ansi
						Return TempPtr
				End Select
			Else
				Return @xRtl.xywh_library_xrtl_memory_snull
			EndIf
		Else
			Return @xRtl.xywh_library_xrtl_memory_snull
		EndIf
	End Function
	
	Function File_Write(sPath As ZString Ptr, sText As ZString Ptr, iSize As UInteger) As UInteger Export
		If iSize = 0 Then
			iSize = strlen(sText)
		EndIf
		Function = xRtl.File.Write(sPath, sText, 0, iSize)
		xRtl.File.Cut(sPath, iSize)
	End Function
	
	Function File_WriteEx(sPath As ZString Ptr, sText As ZString Ptr, iAddr As UInteger, iSize As UInteger, eChar As UInteger) As UInteger Export
		If iSize = 0 Then
			iSize = strlen(sText)
		EndIf
		Select Case eChar
			Case 1
				' unicode
				sText = xRtl.Charset.A2W(sText, iSize)
				iSize = wcslen(Cast(Any Ptr, sText))
			Case 2
				' utf-8
				sText = xRtl.Charset.A2U(sText, iSize)
				iSize = strlen(sText)
			Case Else
				' ansi
				
		End Select
		Function = xRtl.File.Write(sPath, sText, iAddr, iSize)
		xRtl.File.Cut(sPath, iSize)
	End Function
	
	Function File_Append(sPath As ZString Ptr, sText As ZString Ptr, iSize As UInteger) As UInteger Export
		If iSize = 0 Then
			iSize = strlen(sText)
		EndIf
		Dim iLen As UInteger = xRtl.File.Size(sPath)
		Return xRtl.File.Write(sPath, sText, iLen, iSize)
	End Function
	
	Function File_AppendEx(sPath As ZString Ptr, sText As ZString Ptr, iSize As UInteger, eChar As UInteger) As UInteger Export
		If iSize = 0 Then
			iSize = strlen(sText)
		EndIf
		Select Case eChar
			Case 1
				' unicode
				sText = xRtl.Charset.A2W(sText, iSize)
				iSize = wcslen(Cast(Any Ptr, sText))
			Case 2
				' utf-8
				sText = xRtl.Charset.A2U(sText, iSize)
				iSize = strlen(sText)
			Case Else
				' ansi
				
		End Select
		Dim iLen As UInteger = xRtl.File.Size(sPath)
		Return xRtl.File.Write(sPath, sText, iLen, iSize)
	End Function
	
	Function File_Len(sPath As ZString Ptr) As UInteger Export
		Return xRtl.File.Size(sPath)
	End Function
	
	Function File_LenEx(sPath As ZString Ptr) As ULongInt Export
		Dim hFile As HANDLE = xRtl.File.Open(sPath, -1)
		If hFile Then
			Dim iSize As LARGE_INTEGER
			GetFileSizeEx(hFile, @iSize)
			Function = iSize.QuadPart
		EndIf
		CloseHandle(hFile)
	End Function
	
	Function xFile_Create Alias "File_Create" (sPath As ZString Ptr) As Integer Export
		Return xRtl.File.Create(sPath)
	End Function
	
	Function File_Copy(sPathSrc As ZString Ptr, sPathDst As ZString Ptr) As Integer Export
		Return CopyFile(sPathSrc, sPathDst, FALSE)
	End Function
	
	Function File_Move(sPathSrc As ZString Ptr, sPathDst As ZString Ptr) As Integer Export
		Return MoveFileEx(sPathSrc, sPathDst, MOVEFILE_REPLACE_EXISTING Or MOVEFILE_COPY_ALLOWED Or MOVEFILE_WRITE_THROUGH)
	End Function
	
	Function File_Rename(sPathSrc As ZString Ptr, sPathDst As ZString Ptr) As Integer Export
		Return MoveFileEx(sPathSrc, sPathDst, MOVEFILE_COPY_ALLOWED Or MOVEFILE_WRITE_THROUGH)
	End Function
	
	Function File_Exists(sPath As ZString Ptr) As Integer Export
		Return xRtl.File.Exists(sPath)
	End Function
	
	Function Folder_LenEx(sPath As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As ULongInt Export
		Dim Info As Folder_Execute_Info
		Info.Filter = sFilt
		Info.FileSize = 0
		Info.IsRecu = iRecu
		xRtl.File.Scan(sPath, sFilt, 0, 0, 0, @SizePath_Proc, Cast(Integer, @Info))
		Return Info.FileSize
	End Function
	
	Function Folder_Len(sPath As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As UInteger Export
		Return Folder_LenEx(sPath, sFilt, iRecu)
	End Function
	
	Function Folder_Create(sPath As ZString Ptr) As Integer Export
		Dim iLen As UInteger = strlen(sPath)
		For i As Integer = 0 To iLen - 1
			Select Case Cast(UByte Ptr, sPath)[i]
				Case 58
					i += 1
				Case 92, 47
					Dim bTmp As UByte = Cast(UByte Ptr, sPath)[i]
					Cast(UByte Ptr, sPath)[i] = 0
					CreateDirectory(sPath, NULL)
					Cast(UByte Ptr, sPath)[i] = bTmp
			End Select
		Next
		Return CreateDirectory(sPath, NULL)
	End Function
	
	Function Folder_Copy(sPathSrc As ZString Ptr, sPathDst As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As UInteger Export
		Dim Info As Folder_Execute_Info
		Info.DstPath = sPathDst
		Info.Filter = sFilt
		Info.FileCount = 0
		Info.IsRecu = iRecu
		Folder_Create(sPathDst)
		xRtl.File.Scan(sPathSrc, sFilt, 0, 0, 0, @CopyPath_Proc, Cast(Integer, @Info))
		Return Info.FileCount
	End Function
	
	Function Folder_Move(sPathSrc As ZString Ptr, sPathDst As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As UInteger Export
		Dim Info As Folder_Execute_Info
		Info.DstPath = sPathDst
		Info.Filter = sFilt
		Info.FileCount = 0
		Info.IsRecu = iRecu
		Folder_Create(sPathDst)
		xRtl.File.Scan(sPathSrc, sFilt, 0, 0, 0, @MovePath_Proc, Cast(Integer, @Info))
		RemoveDirectory(sPathSrc)
		Return Info.FileCount
	End Function
	
	Function Folder_Delete(sPath As ZString Ptr, sFilt As ZString Ptr, iRecu As Integer) As UInteger Export
		Dim Info As Folder_Execute_Info
		Info.Filter = sFilt
		Info.FileCount = 0
		Info.IsRecu = iRecu
		xRtl.File.Scan(sPath, sFilt, 0, 0, 0, @DeletePath_Proc, Cast(Integer, @Info))
		RemoveDirectory(sPath)
		Return Info.FileCount
	End Function
	
	Function Folder_Exists(sPath As ZString Ptr) As Integer Export
		If PathFileExists(sPath) Then
			If PathIsDirectory(sPath) Then
				Return -1
			EndIf
		EndIf
	End Function
	
End Extern
